package iris_controller

import (
	"fmt"
	"github.com/kataras/iris/v12"
	"gluenet/internal/glue-srvp/domain"
	"gluenet/internal/glue-srvp/domain/vo"
	"gluenet/internal/pkg/infra"
	"gluenet/internal/pkg/infra/prepare"
)

func init() {
	prepare.RegisterAuthController(func() {
		controller := NewTagController()
		prepare.InjectAuthController(func() *Tag {
			return controller
		})
	})
}

type Tag struct {
	Tag *domain.Tag
}

func NewTagController() *Tag {
	r := &Tag{}
	prepare.FetchDependency(&r.Tag)
	return r
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/tag/query
func (c *Tag) GetQuery(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	//params := ctx.URLParams()
	var query = make(map[string]interface{}, len(ctx.URLParams()))
	for k, v := range ctx.URLParams() {
		query[k] = v
	}
	tag, err := c.Tag.FindTagDetail(auth, query)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(tag)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/tag/all
func (c *Tag) GetAll(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	tag, err := c.Tag.FindTagDetail(auth, map[string]interface{}{})
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(tag)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/tag/group/query
func (c *Tag) GetGroupQuery(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	//params := ctx.URLParams()
	var query = make(map[string]interface{}, len(ctx.URLParams()))
	for k, v := range ctx.URLParams() {
		query[k] = v
	}
	tag, err := c.Tag.FindGroup(auth, query)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(tag)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/tag/group/all
func (c *Tag) GetGroupAll(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	tag, err := c.Tag.FindGroup(auth, map[string]interface{}{})
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(tag)
}

// Create serves
// Method:   POST
// Resource: http://localhost:8080/apis/tag/create
func (c *Tag) PostCreate(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.CreateTagsReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}

	var tags []interface{}
	for _, v := range req.Tags {
		tag, err := c.Tag.CreateTag(auth, v)
		if err != nil {
			return infra.ResponseReqErr(fmt.Errorf("create tag %v", err), nil)
		}
		tags = append(tags, tag)
	}
	return infra.ResponseOK(tags)
}

// Update serves
// Method:   POST
// Resource: http://localhost:8080/apis/tag/update
func (c *Tag) PostUpdate(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.UpdateTagReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}

	tag, err := c.Tag.UpdateTag(auth, req)
	if err != nil {
		return infra.ResponseReqErr(fmt.Errorf("create tag %v", err), nil)
	}
	return infra.ResponseOK(tag)
}

// Create serves
// Method:   POST
// Resource: http://localhost:8080/apis/tag/group/create
func (c *Tag) PostGroupCreate(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.CreateTagGroupReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}

	tagGrp, err := c.Tag.CreateTagGroup(auth, req)
	if err != nil {
		return infra.ResponseReqErr(fmt.Errorf("create tag group %v", err), nil)
	}
	return infra.ResponseOK(tagGrp)
}

// Update serves
// Method:   POST
// Resource: http://localhost:8080/apis/tag/group/update
func (c *Tag) PostGroupUpdate(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.UpdateTagGroupReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}

	tagGrp, err := c.Tag.UpdateTagGroup(auth, req)
	if err != nil {
		return infra.ResponseReqErr(fmt.Errorf("create tag group %v", err), nil)
	}
	return infra.ResponseOK(tagGrp)
}

// Delete serves
// Method:   DELETE
// Resource: http://localhost:8080/apis/tag/delete
func (c *Tag) DeleteDelete(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.DeleteTagReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}
	for _, id := range req.IDs {
		_, err := c.Tag.DeleteTag(auth, id)
		if err != nil {
			return infra.ResponseReqErr(err, nil)
		}
	}
	return infra.ResponseOK(nil)
}

// Delete serves
// Method:   DELETE
// Resource: http://localhost:8080/apis/tag/group/delete
func (c *Tag) DeleteGroupDelete(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.DeleteTagGroupReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}
	for _, id := range req.IDs {
		_, err := c.Tag.DeleteTagGroup(auth, id)
		if err != nil {
			return infra.ResponseReqErr(err, nil)
		}
	}
	return infra.ResponseOK(nil)
}

// Create serves
// Method:   Post
// Resource: http://localhost:8080/apis/tag/tag
func (c *Tag) PostTag(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.CreateTagObjReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}
	for _, tagObj := range req.Tags {
		_, err := c.Tag.CreateTagObj(tagObj)
		if err != nil {
			return infra.ResponseReqErr(err, nil)
		}
	}
	return infra.ResponseOK(nil)
}

// Create serves
// Method:   Post
// Resource: http://localhost:8080/apis/tag/untag
func (c *Tag) PostUntag(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	var req = vo.UntagTagObjReq{}
	if err := ctx.ReadJSON(&req); err != nil {
		return infra.ResponseReqErr(fmt.Errorf("read req %v", err), nil)
	}
	for _, tagObj := range req.Tags {
		_, err := c.Tag.UnTagObj(tagObj)
		if err != nil {
			return infra.ResponseReqErr(err, nil)
		}
	}
	return infra.ResponseOK(nil)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/tag/objs/query
func (c *Tag) GetObjsQuery(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	tagValue := ctx.URLParam("tag")

	res, err := c.Tag.FindTagObj(auth, tagValue)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	return infra.ResponseOK(res)

	//var query = map[string]interface{}{}
	//query["value"] = tagValue
	//
	//tag, err := c.Tag.TagFactory.FindTag(query)
	//if err != nil {
	//	return infra.ResponseReqErr(err, nil)
	//}
	//tagID := tag[0].ID
	//var queryTagObj = map[string]interface{}{}
	//queryTagObj["tag_id"] = tagID
	//tagObjs, err := c.Tag.FindTagObj(queryTagObj)
	//if err != nil {
	//	return infra.ResponseReqErr(err, nil)
	//}
	//
	//var res vo.TagObjDetailRes
	//
	//config := NewConfigController()
	//instance := NewInstanceController()
	//for _, tagObj := range tagObjs {
	//	var q = map[string]interface{}{}
	//	q["id"] = tagObj.ObjID
	//	if tagObj.ObjType == "config" {
	//		r, err := config.Config.FindByUser(user_id, admin, q)
	//		if err != nil {
	//			return infra.ResponseReqErr(err, nil)
	//		}
	//		res.Configs = append(res.Configs, r)
	//	} else if tagObj.ObjType == "instance" {
	//		r, err := instance.Instance.FindByUser(admin, user_id, q)
	//		if err != nil {
	//			return infra.ResponseReqErr(err, nil)
	//		}
	//		res.Instances = append(res.Instances, r)
	//	}
	//}
	//return infra.ResponseOK(res)
}

// Get serves
// Method:   GET
// Resource: http://localhost:8080/apis/tag/objs/all
func (c *Tag) GetObjsAll(ctx iris.Context) *infra.Response {
	var auth = infra.AuthInfo{}
	auth.UserId = ctx.Values().GetString("user_id")
	auth.GroupId, _ = ctx.Values().GetInt64("group_id")
	auth.AuthLevel, _ = ctx.Values().GetInt64("auth_level")

	c.Tag.FindTagDetail(auth, nil)

	res, err := c.Tag.FindAllTagObj(auth)
	if err != nil {
		return infra.ResponseReqErr(err, nil)
	}
	//return infra.ResponseOK(res)
	return infra.ResponseOK(res)
}
